/* Copyright 2024 Coremail
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { base64Decode, decodeCharset, qpDecode } from 'coremail/src/main/ets/utils/encodings';
import type { IBuffer, Mime,
} from 'coremail/Index';
import { getMimeDecodedBody } from 'coremail/src/main/ets/utils/mime';
import { FileBuffer } from '../basedata/FileBuffer';
import { StringUtil } from './StringUtil';
import { ExtVsMimeDict } from './MimeExtMap';
import { FileUtil } from './FileUtil';

export class ParseUtil {
  static async decodeMimePartToString(part: Mime): Promise<string> {
    let b: Uint8Array | undefined = await ParseUtil.decodeMimePartToBlob(part);
    let s = "";
    if (b) {
      const decodedString = decodeCharset(b, part.contentType.params.charset || "utf-8");
      if (decodedString.length) {
        s = decodedString;
      }
    }
    part.encoding = 'utf-8';
    return s;
  }

  static async decodeMimePartToBlob(part: Mime): Promise<Uint8Array> {
    const stream = part.body;
    const ss: string[] = [];
    for await (const chunk of stream) {
      ss.push(chunk);
    }
    let s: string = ss.join("");
    let b: Uint8Array | undefined;
    if (part.encoding == "base64") {
      b = base64Decode(s);
    } else if (part.encoding == "quoted-printable") {
      b = qpDecode(s);
    }
    return b
  }


  /**
   * 返回一个以指定filePath创建的IBuffer
   * @param part
   * @param filePath
   * @returns
   */
  static async decodeMimePartToBuffer(part: Mime,filePath:string): Promise<IBuffer> {
    let buffer = getMimeDecodedBody(part);
    part.encoding = '8bit';
    FileUtil.mkFileDirRecursively(filePath);
    const f = new FileBuffer(filePath);

    for await (const chunk of buffer.readRaw()) {
      await f.feed(chunk);
    }
    await f.end();
    return f;
  }
}
